<?php

/**
 * Contains a class to display /user/edit_store.php.
 *
 * PHP Version 5
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @author   Spencer Hakim <hakims@rpi.edu>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
 */
 
/** @uses getStateList To get an array of U.S. states. */
require_once 'function_getstatelist.php';
 
/** @uses valueOf For safe handling of arrays. */
require_once 'function_valueof.php';
 
/**
 * A class to display /user/edit_store.php.
 *
 * @category BuyLocal
 * @package  BuyLocal
 * @author   Kevin Fodness <kevin.fodness@gmail.com>
 * @author   Mike Pennisi <mpennisi@andrew.cmu.edu>
 * @author   Aaron Ryden <aryden@gmail.com>
 * @author   Spencer Hakim <hakims@rpi.edu>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://code.google.com/p/buylocalopensourcerensselaer/
 */ 
class PageEditStore extends Page
{
    /**
     * State variable for whether or not to update the store info.
     *
     * @access private
     * @var bool
     */
    private $_updateInfo;

    /**
     * State variable for whether or not to delete the store.
     *
     * @access private
     * @var bool
     */
    private $_delete;
    
    /**
     * The store which we are currently editing.
     *
     * @access private
     * @var bool
     */
    private $_store;

    /**
     * Contains the error text, if any, to display.
     *
     * @access public
     * @var string
     */
    public $error;
    
    /**
     * Constructor function.  Calls the parent constructor and sets the title.
     */
    public function __construct()
    {
        parent::__construct();
        if (valueOf($_GET, 'storeid') != '') {
            $this->_store = $this->db->getStoreById(
                valueOf($_GET, 'storeid'), $this->user->zip->latitude,
                $this->user->zip->longitude, true
            );
        }

        if (count($_POST) > 0) {
            $this->_updateInfo = true;
        } else if (valueOf($_GET, 'action') == 'delete') {
            $this->_delete = true;
        }
        parent::setTitle('Edit Store');
    }
    
    /**
     * Function to print an INPUT form field.
     *
     * @param string $id        The value to use for the id and name fields.
     * @param string $label     The string to insert between the <label> tags.
     * @param string $type      The type of the input field (text, password).
     * @param string $maxlength The maximum length for the input field.
     * @param string $value     The string to insert into the value attribute.
     *
     * @access private
     * @return null
     */
    private function _printFormField($id, $label, $type, $maxlength, $value)
    {
        $id        = encode($id);
        $label     = encode($label);
        $type      = encode($type);
        $maxlength = encode($maxlength);
        $value     = encode($value);
        
        echo '  <div>', "\n",
            '   <label for="', $id, '">', $label, ':</label>', "\n",
            '   <input id="', $id, '" name="', $id, '" type="', $type, '" ',
            'maxlength="', $maxlength, '" value="', encode($value), '" />', "\n",
            '  </div>', "\n";
    }
    
    /**
     * Function for printing the States dropdown box.
     *
     * @access private
     * @return string
     */
    private function _printStates()
    {
        $stateList = getStateList();
        $keys = array_keys($stateList);
        echo '  <div>', "\n",
            '   <label for="state">State:</label>', "\n",
            '   <select name="state" id="state" style="width:181px;">', "\n";
        foreach ($keys as $state) {
            if ($this->_store->state == $state) {
                echo '    <option value="', $state, '" selected="selected">';
            } else {
                echo '    <option value="', $state, '">';
            }
            
            echo $stateList[$state], '</option>', "\n";
        }
        echo '   </select>', "\n",
            '  </div>', "\n";
    }

    /**
     * Function for printing the Country form field.
     *
     * @access private
     * @return null
     */
    private function _printCountryField()
    {
        echo '  <div>', "\n",
            '   <label for="country">Country:</label>', "\n",
            '   <select name="country" id="country" style="width:181px;">',
            "\n";
        
        foreach ($this->db->getCountries() as $country) {
            if ($this->_store->country == $country['id']) {
                echo '    <option value="', $country['id'],
                    '" selected="selected">';
            } else {
                echo '    <option value="', $country['id'], '">';
            }

            echo $country['name'], '</option>', "\n";
        }
        echo '   </select>', "\n",
            '  </div>', "\n";
    }

    /**
     * Function for printing the Category multi-select form field.
     *
     * @access private
     * @return null
     */
    private function _printCategoryField()
    {
        echo '  <div>', "\n",
            '   <label for="country">Categories:</label>', "\n",
            '   <select name="categories[]" id="categories" multiple="multiple" ',
            'style="width:181px; height:150px;">', "\n";
        
        $cats = $this->_store->categories;
        
        $categories = array();
        foreach ($cats as $cat) {
            $categories[] = $cat->id;
        }
        
        foreach ($this->db->getCategories() as $category) {
            if (in_array($category['id'], $categories)) {
                echo '<option value="', $category['id'],
                    '" selected="selected">';
            } else {
                echo '<option value="', $category['id'], '">';
            }

            echo $category['name'], '</option>', "\n";
        }
        echo '   </select>', "\n",
            '  </div>', "\n";
    }

    /**
     * Function for printing the Events multi-select form field.
     *
     * @access private
     * @return null
     */
    private function _printEventsField()
    {
        echo '  <div>', "\n",
            '   <label for="country">Events:</label>', "\n",
            '   <select name="events[]" id="events" multiple="multiple" ',
            'style="width:181px; height:150px;">', "\n";
        
        $events2 = $this->_store->events;
        
        $events = array();
        foreach ($events2 as $ev) {
            $events[] = $ev->id;
        }
        $eventCollection = $this->db->getEvents(
            1, $this->user->zip->latitude, $this->user->zip->longitude
        );
        foreach ($eventCollection as $event) {
            if (in_array($event->id, $events)) {
                echo '<option value="', $event->id,
                    '" selected="selected">';
            } else {
                echo '<option value="', $event->id, '">';
            }

            echo $event->name, '</option>', "\n";
        }
        echo '   </select>', "\n",
            '  </div>', "\n";
    }
    
    /**
     * Function to print the Edit Store form.
     *
     * @access private
     * @return null
     */
    private function _printEditStoreForm()
    {
        if ($this->error != '') {
            printError($this->error, 1);
        }

        echo ' <form id="newstore" method="post">', "\n",
            '  <h2>Basic Information</h2>', "\n";
        $this->_printFormField(
            'name', 'Store name', 'text', L_STORENAME, $this->_store->name
        );
        $this->_printFormField(
            'description', 'Description', 'text', null, $this->_store->description
        );
        $this->_printFormField(
            'address', 'Address', 'text', L_STOREADDR, $this->_store->address
        );
        $this->_printFormField(
            'city', 'City', 'text', L_STOREADDR, $this->_store->city
        );
        $this->_printStates();
        $this->_printFormField(
            'storezip', 'Zip Code', 'text', L_ZIP, $this->_store->zip
        );
        $this->_printCountryField();
        
        echo '  <h2>Contact Information</h2>', "\n";
        if (count($this->_store->emailAddresses) > 0) {
            $this->_printFormField(
                'email', 'Email Address', 'text', L_EMAIL,
                $this->_store->emailAddresses[0]->address
            );
        } else {
            $this->_printFormField('email', 'Email Address', 'text', L_EMAIL, '');
        }

        if (count($this->_store->phoneNumbers) > 0) {
            $this->_printFormField(
                'phonenum', 'Phone Number', 'text', L_PHONE,
                $this->_store->phoneNumbers[0]->number
            );
        } else {
            $this->_printFormField('phonenum', 'Phone Number', 'text', L_PHONE, '');
        }

        if (count($this->_store->faxNumbers) > 0) {
            $this->_printFormField(
                'fax', 'Fax Number', 'text', L_PHONE,
                $this->_store->faxNumbers[0]->number
            );
        } else {
            $this->_printFormField('fax', 'Fax Number', 'text', L_PHONE, '');
        }
        
        echo '  <h2>Store Content</h2>', "\n";
        $this->_printCategoryField();
        
        echo '  <h2>Linked Events</h2>', "\n";
        $this->_printEventsField();
        
        echo '  <div>', "\n",
            '   <input type="submit" value="Update Store"',
            ' class="button" />', "\n",
            '  </div>', "\n",
            ' </form>', "\n",
            ' <h2>Delete Store</h2>', "\n",
            ' <p class="centered">', "\n",
            '  <a href="?action=delete" onclick="return',
            ' confirm(\'Are you sure you wish to delete this store?\');">',
            'Delete Store</a>', "\n",
            ' </p>', "\n",
            ' <script type="text/javascript"',
            ' src="../scripts/newstorefocus.js">',
            '</script>', "\n";
    }
    
    /**
     * Function to update a store.
     *
     * @access private
     * @return null
     */
    private function _updateStoreAction()
    {
        $name       = valueOf($_POST, 'name');
        $desc       = valueOf($_POST, 'description');
        $addr       = valueOf($_POST, 'address');
        $city       = valueOf($_POST, 'city');
        $state      = valueOf($_POST, 'state');
        $zip        = valueOf($_POST, 'storezip');
        $country    = valueOf($_POST, 'country');
        $categories = valueOf($_POST, 'categories') != ''
            ? valueOf($_POST, 'categories')
            : array();
        $events     = valueOf($_POST, 'events') != ''
            ? valueOf($_POST, 'events')
            : array();
        $email      = valueOf($_POST, 'email');
        $emaildesc  = valueOf($_POST, 'emaildesc');
        $phonenum   = valueOf($_POST, 'phonenum');
        $phonedesc  = valueOf($_POST, 'phonedesc');
        $fax        = valueOf($_POST, 'fax');
        $faxdesc    = valueOf($_POST, 'faxdesc');

        /** Verify ZIP code. */
        if (strlen($zip) > L_ZIP) {
            $this->error = 'The Zip Code you provided is not valid.';
            return false;
        }
        $zip = $this->db->getZipByZip($zip);
        if (!$zip) {
            $this->error = 'The Zip Code you provided is not valid.';
            return false;
        }
        
        /** Get name of country ID. */
        $countries     = $this->db->getCountries();
        $countryLookup = "United States";
        foreach ($countries as $ctry) {
            if ($ctry['id'] == $country) {
                $countryLookup = $ctry['name'];
                break;
            }
        }
        
        /** Geocode address into Lat/Long pair. */
        $request_url = GM_GEOCODE_URL. '&q=' . urlencode(
            $addr . ' ' . $city . ',' . $state . ' ' . $zip->zip . ' '
            . $countryLookup
        );
        $xml         = simplexml_load_file($request_url)
            or trigger_error('Failed to call Geocode API', E_USER_ERROR);
        $status      = $xml->Response->Status->code;
        if ($status == "200") {
            //Format: Longitude, Latitude, Altitude
            $coordinates = split(
                ",", $xml->Response->Placemark->Point->coordinates
            );
        } else {
            trigger_error('Geocode API status error: ' .$status, E_USER_ERROR);
        }

        /** Build phone number array. */
        $phoneNumbers = array();
        if ($phonenum != '') {
            if ($phonedesc == '') {
                $phonedesc = 'Main';
            }
            $phoneNumbers[] = new Phone($phonenum, $phonedesc);
        }

        /** Build email array. */
        $emails = array();
        if ($email != '') {
            if ($emaildesc == '') {
                $emaildesc = 'Main';
            }
            $emails[] = new Email($email, $emaildesc);
        }

        /** Build fax array. */
        $faxes = array();
        if ($fax != '') {
            if ($faxdesc == '') {
                $faxdesc = 'Main';
            }
            $faxes[] = new Fax($fax, $faxdesc);
        }

        /** Build category array. */
        $cats = array();
        foreach ($categories as $cat) {
            $cats[] = $this->db->getCategoryById($cat);
        }

        /** Link/unlink Store/events */
        $eventsCollection = $this->db->getEvents(
            1, $this->user->zip->latitude, $this->user->zip->longitude
        ); 
        foreach ($eventsCollection as $event) {
            if (in_array($event->id, $events)) {
                $this->db->linkStoreAndEvent($this->_store->id, $event->id);
            } else {
                $this->db->unlinkStoreAndEvent($this->_store->id, $event->id);
            }
        }

        $events = $this->db->getEventsByStoreId($this->_store->id);

        /** Add Store to database. */
        $store = new Store($this->_store->id, $name, $desc, '', $addr, $city,
            $state, $zip->zip, $country, $coordinates[1], $coordinates[0],
            $cats, $phoneNumbers, $faxes, $emails, $this->_store->imagePath,
            $this->_store->distance, $events);

        $this->db->deleteStore($this->_store);
        $result = $this->db->createStore($this->user, $store);
        if ($result !== true) {
            $this->error = $result;
            return false;
        }
        
        $this->_store = $store;
        return true;
    }
    
    /**
     * Function to display the page.
     *
     * @access public
     * @return null
     */
    public function display()
    {
        if ($this->_store != null
            && ($this->db->isStoreOwner($this->user->id, $this->_store)
            || $this->user->role == R_ADMIN)
            && $this->_updateInfo
        ) {
            $this->_updateStoreAction();
        }
        
        parent::printHeader();
        if ($this->user->role == R_GUEST) {
            echo 'Please <a title="Click to login" href="',
            RELATIVE_PATH, 'login.php">login</a> first.';
        
        } else if ($this->_store != null
            && ($this->db->isStoreOwner($this->user->id, $this->_store)
            || $this->user->role == R_ADMIN)
            && $this->_delete
        ) {
            $this->db->deleteStore($this->_store);
            echo 'Store deleted.';
            
        } else if ($this->_store != null
            && ($this->db->isStoreOwner($this->user->id, $this->_store)
            || $this->user->role == R_ADMIN)
        ) {
            $this->_printEditStoreForm();

        } else {
            echo 'Valid store not selected.';
        }
        parent::printFooter();
    }
}

?>